use crate::model::{MoonModel, MOONH, MOONW};
use log::info;
use tge::{
    context::Context,
    event::{event_check, event_register, timer_fire, timer_register},
    game::{Model, Render},
    render::sprite::{BorderType, Borders, Sprite, Sprites},
    render::style::{Color, Style},
    render::terminal::Term,
    util::Rect,
};

pub struct MoonRender {
    pub term: Term,
    pub main_scene: Sprites,
    pub imgs: Sprites,
}

impl MoonRender {
    pub fn new() -> Self {
        let t = Term::new();
        let mut bs = Sprites::new("main");
        let mut back = Sprite::new(0, 0, MOONW as u16, MOONH as u16);
        back.load_esc("assets/moon/back.txt", 0, 0);
        bs.add(back);

        //背景
        let mut s = Sprites::new("bk");
        let mut tsback = Sprite::new(0, 0, MOONW as u16, MOONH as u16);
        tsback.copy_content(&bs[0]);
        s.add_by_tag(tsback, "back");
        let mut ball = Sprite::new(36, 20, 30, 30);
        ball.load_esc("assets/moon/ball.txt", 0, 0);
        s.add_by_tag(ball, "ball");

        /*event_register("Moon.RedrawGrid", "draw_grid");
        timer_register("Moon.TestTimer", 0.15, "test_timer");
        timer_fire("Moon.TestTimer", 8u8);*/

        Self {
            term: t,
            main_scene: s,
            imgs: bs,
        }
    }

    pub fn draw_fighter<G: Model>(&mut self, context: &mut Context, model: &mut G) {
        let d = model.as_any().downcast_ref::<MoonModel>().unwrap();
        let ml = self.main_scene.get_by_tag("ball");
        let idx = context.stage / 3;
        //let fc = ["-", "\\", "|", "/"];
        //let fc = ["▉","▊","▋","▌","▍","▎","▏","▎","▍","▌","▋","▊","▉"];
        let fc = ["◐", "◓", "◑", "◒"];
        ml.content.set_str(
            3,
            2,
            fc[idx as usize % fc.len()],
            Style::default().fg(Color::Indexed(203)),
        );
        ml.set_pos(d.mainship_pos.x, d.mainship_pos.y);
    }

    pub fn draw_back<G: Model>(&mut self, context: &mut Context, _model: &mut G) {
        if context.stage % 3 != 0 {
            return;
        }
        //let d = model.as_any().downcast_ref::<MoonModel>().unwrap();
        let ml = self.main_scene.get_by_tag("back");
        let idx = context.stage as u16 % MOONH as u16;
        ml.content
            .blit(
                0,
                0,
                &self.imgs[0].content,
                Rect::new(0, MOONH as u16 - idx, MOONW as u16, idx as u16),
            )
            .unwrap_or_else(|e| {
                info!("error:{:?}", e);
                (0, 0)
            });
        ml.content
            .blit(
                0,
                idx,
                &self.imgs[0].content,
                Rect::new(0, 0, MOONW as u16, MOONH as u16 - idx),
            )
            .unwrap();
    }
}

impl Render for MoonRender {
    fn init(&mut self, ctx: &mut Context) {
        ctx.adapter.init(
            MOONW as u16 + 2,
            MOONH as u16 + 4,
            2.0,
            2.0,
            "moon".to_string(),
        );
        self.term.init(ctx);
    }

    fn handle_event<G: Model>(&mut self, _context: &mut Context, _data: &mut G, _dt: f32) {
        /*if event_check("Moon.RedrawGrid", "draw_grid") {
        }*/
    }

    fn handle_timer<G: Model>(&mut self, _context: &mut Context, _model: &mut G, _dt: f32) {
        /*if event_check("Moon.TestTimer", "test_timer") {
            timer_fire("Moon.TestTimer", 8u8);
        }*/
    }

    fn draw<G: Model>(&mut self, context: &mut Context, data: &mut G, _dt: f32) {
        info!("render draw.....");
        self.draw_fighter(context, data);
        self.draw_back(context, data);
        self.term
            .draw(context, |f| {
                self.main_scene.render_all(f);
            })
            .unwrap();
    }
}
